//Given a string s represents the serialization of a nested list, implement a pa
//rser to deserialize it and return the deserialized NestedInteger. 
//
// Each element is either an integer or a list whose elements may also be intege
//rs or other lists. 
//
// 
// Example 1: 
//
// 
//Input: s = "324"
//Output: 324
//Explanation: You should return a NestedInteger object which contains a single 
//integer 324.
// 
//
// Example 2: 
//
// 
//Input: s = "[123,[456,[789]]]"
//Output: [123,[456,[789]]]
//Explanation: Rteurn a NestedInteger object containing a nested list with 2 ele
//ments:
//1. An integer containing value 123.
//2. A nested list containing two elements:
//    i.  An integer containing value 456.
//    ii. A nested list with one element:
//         a. An integer containing value 789
// 
//
// 
// Constraints: 
//
// 
// 1 <= s.length <= 5  104 
// s consists of digits, square brackets "[]", negative sign '-', and commas ','
//. 
// s is the serialization of valid NestedInteger. 
// 
// Related Topics 栈 字符串 
// 👍 59 👎 0


package leetcode.editor.cn;

import java.util.*;

//Java：Mini Parser
class P385MiniParser {
    public static void main(String[] args) {
        NestedInteger nestedInteger = new P385MiniParser().new NestedInteger(123);
        NestedInteger nestedInteger1 = new P385MiniParser().new NestedInteger(456);
        NestedInteger nestedInteger2 = new P385MiniParser().new NestedInteger(789);
        nestedInteger.add(nestedInteger1);
        nestedInteger1.add(nestedInteger2);
        System.out.println(nestedInteger);
        NestedInteger deserialize = new P385MiniParser().deserialize("[123,123]");
        System.out.println(deserialize);

        // TO TEST
    }
    //leetcode submit region begin(Prohibit modification and deletion)

    // This is the interface that allows for creating nested lists.
    // You should not implement it, or speculate about its implementation
    class NestedInteger {
        // Constructor initializes an empty nested list.

        private List<NestedInteger> list;
        private Integer val;

        public NestedInteger(int item) {
            list = new ArrayList<>();
            val = item;
        }

        public NestedInteger() {
            list = new ArrayList<>();
            val = null;
        }

        // @return true if this NestedInteger holds a single integer, rather than a nested list.
        public boolean isInteger() {
            return this.list.size() == 0 ? true : false;
        }

        // @return the single integer that this NestedInteger holds, if it holds a single integer
        // Return null if this NestedInteger holds a nested list
        public Integer getInteger() {
            return val;
        }

        // Set this NestedInteger to hold a single integer.
        public void setInteger(int value) {
            list.clear();
            this.val = value;
        }

        // Set this NestedInteger to hold a nested list and adds a nested integer to it.
        public void add(NestedInteger ni) {
            list.add(ni);
        }

        // @return the nested list that this NestedInteger holds, if it holds a nested list
        // Return empty list if this NestedInteger holds a single integer
        public List<NestedInteger> getList() {
            return list;
        }

        @Override
        public String toString() {
            ArrayList<Integer> intArr = new ArrayList<>();
            addInteger(this, intArr);
            return intArr.toString();
        }
    }

    public void addInteger(NestedInteger nestedInteger, List<Integer> list) {
        list.add(nestedInteger.getInteger());
        for (NestedInteger ele : nestedInteger.getList()) {
            addInteger(ele, list);
        }
    }

    public NestedInteger deserialize(String s) {
//        [123,[456,[789,8,9]]]
        if (s == null || s.trim().equals("")) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        Deque<String> stack = new ArrayDeque<>();
        Stack<NestedInteger> stackNest = new Stack<>();
        String leftBracket = "[";
        String rightBracket = "]";
        boolean hasChild = false;
        String comma = ",";
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if ('0' <= c && c <= '9') {
                sb.append(c);
            } else {
                if (c == '[') {
                    stack.push(leftBracket);
                } else if (c == ',') {
                    if (sb.length() != 0) {
                        stack.push(sb.toString());
                        sb = new StringBuilder();
                    }
                    stack.push(",");
                    continue;
                } else if (c == ']') {
                    if (sb.length() != 0) {
                        stack.push(sb.toString());
                        sb = new StringBuilder();
                    }
                    while (!stack.peek().equals(leftBracket)) {
                        if (stack.peek().equals(comma)) {
                            stack.pop();
                            String pop = stack.pop();
                            NestedInteger newItem = new NestedInteger(Integer.parseInt(pop));
                            if (hasChild) {
                                if (!stackNest.isEmpty()) {
                                    NestedInteger nestPop = stackNest.pop();
                                    newItem.getList().add(nestPop);
                                }
                            }
                            stackNest.push(newItem);
                        } else {
                            String pop = stack.pop();
                            NestedInteger newItem = new NestedInteger(Integer.parseInt(pop));
                            if (!stackNest.isEmpty()) {
                                NestedInteger nestPop = stackNest.pop();
                                newItem.getList().add(nestPop);
                            }
                            stackNest.push(newItem);
                        }

                    }
                    hasChild = true;
                    stack.pop();
                }
            }
        }
        if (sb.length() != 0) {
            stack.push(sb.toString());
        }
        if (!stack.isEmpty() && stack.size() == 1) {
            return new NestedInteger(Integer.parseInt(stack.pop()));
        } else if (!stack.isEmpty() && stack.size() > 0) {
            NestedInteger result = new NestedInteger(Integer.parseInt(stack.pollFirst()));
            while (!stack.isEmpty()) {
                result.add(new NestedInteger(Integer.parseInt(stack.pollFirst())));
            }
            return result;
        } else {
            NestedInteger result = new NestedInteger(Integer.parseInt(stack.pollFirst()));
            while (!stack.isEmpty()) {
                result.add(new NestedInteger(Integer.parseInt(stack.pollFirst())));
            }
            return result;
        }

    }
//leetcode submit region end(Prohibit modification and deletion)

}